//
// Created by hgx on 2021/12/17.
//

#include "Scene.h"
#include <cereal/archives/json.hpp>
#include <fstream>
#include "Components.h"
#pragma region Basic type for serialize

namespace glm
{
    template <typename Archive>
    void serialize( Archive & ar,float3 & v )
    {
        ar(cereal::make_nvp("x",v.x),cereal::make_nvp("y",v.y),cereal::make_nvp("z",v.z));
    }
}
namespace Component
{
    template <typename Archive,typename T>
    void serialize( Archive & ar,T& v )
    {
        Ubpa::USRefl::TypeInfo<T>::ForEachVarOf(v, [&](const auto& field, auto& var) {
            constexpr auto tstr_NotSerialize = TSTR("NotSerialize");
            if constexpr(!decltype(field.attrs)::Contains(tstr_NotSerialize))
            {
                ar(cereal::make_nvp(field.name.data(),var));
            }
        });
    }
}

#pragma endregion

namespace  Bonnie
{
    uint32_t Scene::AddEntity() {
        return static_cast<uint32_t>(mRegistry.create());
    }

    using namespace Component;
    void Scene::Serialize(const std::string &fileName) {
        auto temp = fileName;

        std::ofstream os(temp);
        cereal::JSONOutputArchive archive(os);

        entt::basic_snapshot snapshot(mRegistry);
        snapshot.entities(archive).component<__ComponentNameSet>(archive);
    }

    void Scene::UnSerialize(const std::string &fileName) {
        mRegistry.clear();

        std::ifstream is(fileName);
        cereal::JSONInputArchive archive(is);

        entt::basic_snapshot_loader loader(mRegistry);
        loader.entities(archive)
                .component<__ComponentNameSet>(archive);
    }
}

